<template>
  <div class="map-container">
    <!-- 主地图容器 -->
    <div
      id="before"
      class="map"
      :class="{ 'compare-mode': isCompareMode }"
    ></div>
    <!-- 对比地图容器 -->
    <div
      id="after"
      class="map"
      :class="{ 'compare-mode': isCompareMode }"
      v-show="isCompareMode"
    ></div>
    <div class="map-divider" v-show="isCompareMode"></div>

    <div v-show="!isCompareMode">
      <ToolsComponent
        ref="toolsRef"
        v-if="map && measureTool"
        :map="map"
        :measureTool="measureTool"
        :toggleCompareMode="toggleCompareMode"
      />
    </div>

    <!-- 左侧地图图层管理 -->
    <LayerManage
      v-if="map"
      ref="leftLayerManageRef"
      :map="map"
      :class="{ 'compare-mode': isCompareMode }"
      class="left-layer-manage"
    />
    <!-- 右侧地图图层管理 -->
    <LayerManage
      v-if="compareMap && isCompareMode"
      ref="rightLayerManageRef"
      :map="compareMap"
      class="right-layer-manage compare-mode"
    />
    <!-- 关闭按钮 -->
    <el-icon
      class="close-btn"
      :size="24"
      @click="toggleCompareMode(false)"
      v-show="isCompareMode"
      ><CircleCloseFilled
    /></el-icon>
  </div>
</template>

<script setup>
import mapboxgl from "mapbox-gl";
import "mapbox-gl/dist/mapbox-gl.css";
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
import { ref, onMounted, onBeforeUnmount } from "vue";
import { MeasureTool } from "@/utils/mapbox/measure";
import { TiandituLayer } from "@/utils/mapbox/tianditu";
import ToolsComponent from "./components/tools.vue";
import LayerManage from "./components/LayerManage.vue";
import { MapCompare } from "@/utils/mapbox/compare";
import { CircleCloseFilled } from "@element-plus/icons-vue";

let map = ref(null); // 主地图实例
let compareMap = ref(null); // 对比地图实例
let measureTool = ref(null); // 测量工具
let Draw = null; // 绘制工具
let tiandituLayer = null; // 天地图工具
let leftLayerManageRef = ref(null); // 左侧图层管理
let rightLayerManageRef = ref(null); // 右侧图层管理
let isCompareMode = ref(false); // 是否为对比模式
let mapCompare = ref(null); // 对比地图
let toolsRef = ref(null); // 工具栏
// 切换对比模式
const toggleCompareMode = (mode) => {
  isCompareMode.value = mode;

  if (mode) {
    if (!mapCompare.value) {
      mapCompare.value = new MapCompare(map.value, tiandituLayer);
    }
    mapCompare.value.initCompareMap();
    compareMap.value = mapCompare.value.getCompareMap();

    // 等待 DOM 更新后重新计算地图大小
    setTimeout(() => {
      mapCompare.value.resize();
    }, 300);
  } else {
    toolsRef.value.updateCurrentTool("");
    // 关闭对比模式
    mapCompare.value?.removeCompareMap();
    compareMap.value = null;

    // 等待 DOM 更新后重新计算地图大小
    setTimeout(() => {
      map.value.resize();
    }, 300);
  }
};

// 暴露方法给工具栏使用
defineExpose({
  toggleCompareMode,
});

const initMap = () => {
  mapboxgl.accessToken =
    "pk.eyJ1IjoiYmVpem91byIsImEiOiJjbGZoeDhycW8waGsxM3FvaHh5cTVwdml5In0.ewZaVrl96N9xk0jFKlu85A";

  // 初始化天地图工具
  tiandituLayer = new TiandituLayer();

  // 使用 before 作为主地图容器
  map.value = new mapboxgl.Map({
    container: "before",
    style: {
      version: 8,
      sources: {},
      layers: [],
    },
    center: [120.476858, 31.358201],
    zoom: 13,
    maxZoom: 17,
    minZoom: 6,
  });

  map.value.on("load", () => {
    // 默认使用电子地图
    tiandituLayer.switchMapStyle(map.value, "vec");

    // 初始化绘制工具
    Draw = new MapboxDraw({
      displayControlsDefault: false,
      controls: {
        point: true,
        line_string: true,
        polygon: true,
        trash: true,
      },
      styles: [
        {
          id: "point-style",
          type: "circle",
          filter: ["all", ["==", "$type", "Point"]],
          paint: {
            "circle-radius": 3,
            "circle-color": "#ff0000",
            "circle-stroke-width": 2,
            "circle-stroke-color": "#ffffff",
          },
        },
        {
          id: "gl-draw-line",
          type: "line",
          filter: ["all", ["==", "$type", "LineString"]],
          paint: {
            "line-color": "#f00",
            "line-width": 2,
          },
        },
        {
          id: "gl-draw-polygon",
          type: "fill",
          filter: ["all", ["==", "$type", "Polygon"]],
          paint: {
            "fill-color": "#f00",
            "fill-opacity": 0.1,
          },
        },
        {
          id: "gl-draw-polygon-stroke",
          type: "line",
          filter: ["all", ["==", "$type", "Polygon"]],
          paint: {
            "line-color": "#f00",
            "line-width": 2,
          },
        },
      ],
    });
    map.value.addControl(Draw, "top-left");

    // 初始化测量工具
    measureTool.value = new MeasureTool(map.value, Draw);
  });
};

onMounted(() => {
  initMap();
});

onBeforeUnmount(() => {
  leftLayerManageRef.value?.removeAllSources();
  rightLayerManageRef.value?.removeAllSources();
  mapCompare.value?.removeCompareMap();
  // 销毁地图
  map.value = null;
});
</script>

<style scoped lang="scss">
.map-container {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;

  .map {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    transition: all 0.3s ease;

    &#before {
      left: 0;
      &.compare-mode {
        width: 50%;
      }
    }

    &#after {
      right: 0;
      &.compare-mode {
        width: 50%;
      }
    }
  }

  .map-divider {
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 4px;
    background-color: #fff;
    transform: translateX(-50%);
    cursor: col-resize;
    z-index: 1;

    &::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 20px;
      height: 40px;
      background-color: #fff;
      border-radius: 20px;
    }
  }

  .left-layer-manage {
    right: 20px;
    transition: all 0.3s ease;

    &.compare-mode {
      right: 50%;
      margin-right: 40px;
    }
  }

  .right-layer-manage {
    right: 20px;
  }

  .close-btn {
    position: absolute;
    top: 2px;
    right: 2px;
    cursor: pointer;
    z-index: 1000;
  }
}
</style>
